- (void)tileViewsFromMinX:(CGFloat)minimumVisibleX toMaxX:(CGFloat)maximumVisibleX { // the upcoming tiling logic depends on there already being at least one label in the visibleLabels array, so // to kick off the tiling we need to make sure there's at least one label if ([_visibleViews count] == 0) { _rightMostVisibleViewIndex = -1; _leftMostVisibleViewIndex = 0; [self placeNewViewOnRight:minimumVisibleX]; } // add labels that are missing on right side UIView *lastView = [_visibleViews lastObject]; CGFloat rightEdge = CGRectGetMaxX([lastView frame]); while (rightEdge < maximumVisibleX) { rightEdge = [self placeNewViewOnRight:rightEdge]; } // add labels that are missing on left side UIView *firstView = _visibleViews[0]; CGFloat leftEdge = CGRectGetMinX([firstView frame]); while (leftEdge > minimumVisibleX) { leftEdge = [self placeNewViewOnLeft:leftEdge]; } // remove labels that have fallen off right edge lastView = [_visibleViews lastObject]; while ([lastView frame].origin.x > maximumVisibleX) { [lastView removeFromSuperview]; [_visibleViews removeLastObject]; lastView = [_visibleViews lastObject]; _rightMostVisibleViewIndex--; if (_rightMostVisibleViewIndex < 0) { _rightMostVisibleViewIndex = self.numberOfItems - 1; } } // remove labels that have fallen off left edge firstView = _visibleViews[0]; while (CGRectGetMaxX([firstView frame]) < minimumVisibleX) { [firstView removeFromSuperview]; [_visibleViews removeObjectAtIndex:0]; firstView = _visibleViews[0]; _leftMostVisibleViewIndex++; if (_leftMostVisibleViewIndex == self.numberOfItems) { _leftMostVisibleViewIndex = 0; } } }
#pragma mark - ver View Tiling
- (CGFloat)placeNewViewOnBottom:(CGFloat)bottomEdge { _bottomMostVisibleViewIndex++; if (_bottomMostVisibleViewIndex == self.numberOfItems) { _bottomMostVisibleViewIndex = 0; } UIView *view; if ([self.infiniteDelegate respondsToSelector:@selector(infiniteScrollView:viewForItemAtIndex:)]) { view = [self.infiniteDelegate infiniteScrollView:self viewForItemAtIndex:_bottomMostVisibleViewIndex]; } if (!view) { view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height)]; } view.tag = 20000 + _bottomMostVisibleViewIndex; [_containerView addSubview:view]; [_visibleViews addObject:view]; // add rightmost label at the end of the array CGRect frame = [view frame]; frame.origin.x = 0; frame.origin.y = bottomEdge; [view setFrame:frame]; returnCGRectGetMaxY(frame); }
- (void)tileViewsFromMinY:(CGFloat)minimumVisibleY toMaxY:(CGFloat)maximumVisibleY { // the upcoming tiling logic depends on there already being at least one label in the visibleLabels array, so // to kick off the tiling we need to make sure there's at least one label if ([_visibleViews count] == 0) { _bottomMostVisibleViewIndex = -1; _topMostVisibleViewIndex = 0; [self placeNewViewOnBottom:minimumVisibleY]; } // add labels that are missing on right side UIView *lastView = [_visibleViews lastObject]; CGFloat bottomEdge = CGRectGetMaxY([lastView frame]); while (bottomEdge < maximumVisibleY) { bottomEdge = [self placeNewViewOnBottom:bottomEdge]; } // add labels that are missing on left side UIView *firstView = _visibleViews[0]; CGFloat topEdge = CGRectGetMinY([firstView frame]); while (topEdge > minimumVisibleY) { topEdge = [self placeNewViewOnTop:topEdge]; } // remove labels that have fallen off right edge lastView = [_visibleViews lastObject]; while ([lastView frame].origin.y > maximumVisibleY) { [lastView removeFromSuperview]; [_visibleViews removeLastObject]; lastView = [_visibleViews lastObject]; _bottomMostVisibleViewIndex--; if (_bottomMostVisibleViewIndex < 0) { _bottomMostVisibleViewIndex = self.numberOfItems - 1; } } // remove labels that have fallen off left edge firstView = _visibleViews[0]; while (CGRectGetMaxY([firstView frame]) < minimumVisibleY) { [firstView removeFromSuperview]; [_visibleViews removeObjectAtIndex:0]; firstView = _visibleViews[0]; _topMostVisibleViewIndex++; if (_topMostVisibleViewIndex == self.numberOfItems) { _topMostVisibleViewIndex = 0; } } }